package com.cloudeasy.core.config;

import com.cloudeasy.core.authorize.AuthorizeConfigManager;
import com.cloudeasy.core.properties.SecurityProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;
import org.springframework.security.oauth2.provider.token.TokenStore;

/**
 * 资源服务器配置
 */
@Configuration
@EnableResourceServer
@EnableConfigurationProperties(SecurityProperties.class)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    /**
     * {@link TokenStore}令牌存储
     */
    private final TokenStore tokenStore;
    /**
     * {@link AuthorizeConfigManager}授权管理器
     */
    private final AuthorizeConfigManager authorizeConfigManager;
    /**
     * {@link GlobalMethodSecurityConfig}中注册的{@link OAuth2WebSecurityExpressionHandler}表达式处理程序
     */
    private final OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler;

    public ResourceServerConfig(TokenStore tokenStore, AuthorizeConfigManager authorizeConfigManager, OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler) {
        this.tokenStore = tokenStore;
        this.authorizeConfigManager = authorizeConfigManager;
        this.oAuth2WebSecurityExpressionHandler = oAuth2WebSecurityExpressionHandler;
    }

    /**
     * 关闭csrf，为{@link AuthorizeConfigManager}授权管理器传入
     * {@link ExpressionUrlAuthorizationConfigurer <HttpSecurity>.ExpressionInterceptUrlRegistry}配置对象
     *
     * @param http {@link HttpSecurity}
     * @throws Exception 异常
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        authorizeConfigManager.config(http.authorizeRequests());
    }

    /**
     * 配置令牌存储，{@link OAuth2WebSecurityExpressionHandler}表达式处理程序
     * （其中配置了自己定义的权限计算器）
     *
     * @param resources {@link ResourceServerSecurityConfigurer}
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.tokenStore(tokenStore)
                .expressionHandler(oAuth2WebSecurityExpressionHandler);
    }
}
